/*
 * Copyright 2019-2025 the original author or authors.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * https://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.iiifi.kite.configuration;

import java.util.*;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

/**
 * kite 配置
 *
 * @author kite@iiifi.com 花朝
 */
@RefreshScope
@ConfigurationProperties("kite")
public class KiteProperties implements EnvironmentAware, EnvironmentCapable {

    @Nullable
    private Environment environment;

    /**
     * 判断是否为 本地开发环境
     */
    @Getter
    @Setter
    private Boolean isLocal = Boolean.FALSE;

    /**
     * kite header 头信息配置
     */
    @Getter
    @Setter
    private KiteHeader headers = new KiteHeader();

    /**
     * 装载自定义配置kite.prop.xxx
     */
    @Getter
    private final Map<String, String> prop = new HashMap<>();

    /**
     * 获取配置
     *
     * @param key key
     * @return value
     */
    @Nullable
    public String get(String key) {
        return get(key, null);
    }

    /**
     * 获取配置
     *
     * @param key key
     * @param defaultValue 默认值
     * @return value
     */
    @Nullable
    public String get(String key, @Nullable String defaultValue) {
        String value = prop.get(key);
        if (!StringUtils.hasText(value)) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取配置
     *
     * @param key key
     * @return int value
     */
    @Nullable
    public Integer getInt(String key) {
        return getInt(key, null);
    }

    /**
     * 获取配置
     *
     * @param key key
     * @param defaultValue 默认值
     * @return int value
     */
    @Nullable
    public Integer getInt(String key, @Nullable Integer defaultValue) {
        String value = prop.get(key);
        if (value != null) {
            return Integer.valueOf(value.trim());
        }
        return defaultValue;
    }

    /**
     * 获取配置
     *
     * @param key key
     * @return long value
     */
    @Nullable
    public Long getLong(String key) {
        return getLong(key, null);
    }

    /**
     * 获取配置
     *
     * @param key key
     * @param defaultValue 默认值
     * @return long value
     */
    @Nullable
    public Long getLong(String key, @Nullable Long defaultValue) {
        String value = prop.get(key);
        if (value != null) {
            return Long.valueOf(value.trim());
        }
        return defaultValue;
    }

    /**
     * 获取配置
     *
     * @param key key
     * @return Boolean value
     */
    @Nullable
    public Boolean getBoolean(String key) {
        String value = prop.get(key);
        return Boolean.getBoolean(value);
    }

    /**
     * 判断是否存在key
     *
     * @param key prop key
     * @return boolean
     */
    public boolean containsKey(String key) {
        return prop.containsKey(key);
    }

    /**
     * 环境，方便在代码中获取
     *
     * @return 环境 env
     */
    public String getEnv() {
        Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null。");
        String env = environment.getProperty("kite.env");
        return env;
    }

    /**
     * 应用名称${spring.application.name}
     *
     * @return 应用名
     */
    public String getName() {
        Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null。");
        return environment.getProperty("spring.application.name", "");
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public Environment getEnvironment() {
        Objects.requireNonNull(environment, "Spring boot 环境下 Environment 不可能为null。");
        return this.environment;
    }

    @Data
    public static class KiteHeader {
        /**
         * traceId Header key 默认 X-Kite-TraceId
         */
        private String traceId = "X-Kite-TraceId";

        /**
         * X-Kite-Language Header key 默认 X-Kite-Language
         */
        public String language = "X-Kite-Language";

        /**
         * X-Kite-Account-Id Header key 默认 X-Kite-Account-Id
         */
        public String accountId = "X-Kite-Account-Id";

        /**
         * X-Kite-Account Header key 默认 X-Kite-Account
         */
        public String xAccount = "X-Kite-Account";

        /**
         * X-Kite-Token Header key 默认 X-Kite-Token
         */
        public String token = "X-Kite-Token";

        /**
         * X-Kite-Device-Id Header key 默认 X-Kite-Device-Id
         */
        public String deviceId = "X-Kite-DeviceId";

        /**
         * X-Kite-Dynamic-Id Header key 默认 X-Kite-Device-Id
         */
        public String dynamicId = "X-Kite-Dynamic-Id";

        /**
         * X-Kite-Nonce Header key 默认 X-Kite-Nonce
         */
        public String nonce = "X-Kite-Nonce";

        /**
         * X-Kite-Timestamp Header key 默认 X-Kite-Timestamp
         */
        public String timestamp = "X-Kite-Timestamp";

        /**
         * X-Kite-Sign Header key 默认 X-Kite-Sign
         */
        public String sign = "X-Kite-Sign";

        /**
         * X-Kite-App-Name Header key 默认 X-Kite-App-Name
         */
        public String appName = "X-Kite-App-Name";

        /**
         * RestTemplate 和 Fegin 透传到下层的 Headers 名称列表
         */
        private List<String> allowed = new ArrayList<>();
    }

    /**
     * 获取需要向下传递的请求头
     *
     * @return AllowHeads
     */
    public List<String> getAllowHeads() {
        // 全局透传请求头：X-Real-IP x-forwarded-for 请求和转发的ip
        String[] allowHeads = new String[] {"X-Real-IP", "X-Forwarded-For"};
        List<String> allowHeadsList = new ArrayList<>(Arrays.asList(allowHeads));
        // 如果有传递 account header 继续往下层传递
        allowHeadsList.add(this.getHeaders().getToken());
        allowHeadsList.add(this.getHeaders().getLanguage());
        allowHeadsList.add(this.getHeaders().getTraceId());
        allowHeadsList.add(this.getHeaders().getDeviceId());
        allowHeadsList.add(this.getHeaders().getDynamicId());
        allowHeadsList.add(this.getHeaders().getXAccount());
        allowHeadsList.add(this.getHeaders().getAccountId());
        // 配置的下传头
        allowHeadsList.addAll(this.getHeaders().getAllowed());
        return allowHeadsList;
    }
}
